package com.darren.framework.dao.impl;

import com.darren.framework.dao.BaseDao;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.SessionFactoryUtils;
import org.springframework.stereotype.Repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Repository(value = "baseDao")
public class BaseDaoImpl implements BaseDao {

    protected Logger logger = LogManager.getLogger(getClass());

    @Autowired
    protected HibernateTemplate template;

    @Autowired
    protected SessionFactory sessionFactory;

    protected Connection getConnection() throws SQLException {
        Connection connection = null;
        connection = SessionFactoryUtils.getDataSource(sessionFactory).getConnection();
        return connection;
    }

    @Override
    public List<Map<String, Object>> getDataMapList(String sql, Object... objs) throws SQLException {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            connection = getConnection();
            pstmt = connection.prepareStatement(sql);
            for (int i = 1; i <= objs.length; i++) {
                pstmt.setObject(i, objs[i]);
            }
            rs = pstmt.executeQuery();
            ResultSetMetaData data = rs.getMetaData();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 0; i < data.getColumnCount(); i++) {
                    map.put(data.getColumnLabel(i + 1), rs.getObject(data.getColumnLabel(i + 1)));
                }
                list.add(map);
            }
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                connection.close();
                pstmt.close();
                rs.close();
            } catch (SQLException e) {
                throw e;
            }
        }
        return list;
    }


    @Override
    public Map<String, Object> getDataMap(String sql, Object... objs) throws SQLException {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            connection = getConnection();
            pstmt = connection.prepareStatement(sql);
            for (int i = 1; i <= objs.length; i++) {
                pstmt.setObject(i, objs[i]);
            }
            rs = pstmt.executeQuery();
            while (rs.next()) {
                ResultSetMetaData data = rs.getMetaData();
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 1; i <= data.getColumnCount(); i++) {
                    map.put(data.getColumnLabel(i), rs.getObject(data.getColumnLabel(i)));
                }
                return map;
            }
        } catch (SQLException e) {
            throw e;
        } finally {
            try {
                connection.close();
                pstmt.close();
                rs.close();
            } catch (SQLException exception) {
                throw exception;
            }
        }
        return null;
    }


}